﻿using System;
using System.Collections.Generic;
using System.Text;

namespace BL
{
    public class Nagruzki
    {
        static Nagruzki instance;
        public static Nagruzki Instance
		{
			get { return instance; }
		}

        List<NagruzkaItem> items = new List<NagruzkaItem>();
        long maxID = 0;

        public Nagruzki(List<Entity> nagrItems)
		{
			instance = this;
            foreach (Entity e in nagrItems)
            {
                items.Add((NagruzkaItem)e);
                if (maxID < e.ID)
                    maxID = e.ID;
            }
            maxID++;
		}

        public NagruzkaItem[] Items
		{
			get { return items.ToArray(); }
		}

        public NagruzkaItem this[string str]
		{
			get
			{
                foreach (NagruzkaItem ni in items)
				{
					if (ni.ToString() == str)
						return ni;
				}
				return null;
			}
		}

        public NagruzkaItem this[long id]
        {
            get
            {
                foreach (NagruzkaItem ni in items)
				{
					if (ni.ID == id)
						return ni;
				}
				return null;
            }
            set
            {
                for (int i = 0; i < items.Count; i++)
                {
                    if (items[i].ID == id)
                    {
                        items[i].Chislo = value.Chislo;
                        items[i].Hour = value.Hour;
                        items[i].SubjectItem = Subjects.Instance[value.SubjectItem.ID];
                        items[i].Theme = value.Theme;
                        return;
                    }
                }
            }
        }

        public long FreeID
        {
            get { return maxID; }
        }

        public void Add(NagruzkaItem ni)
        {
            items.Add(ni);
            if (maxID < ni.ID)
                maxID = ni.ID;
            maxID++;
        }

        public void Delete(long id)
        {
            for (int i=0; i < items.Count; i++)
            {
                if (items[i].ID == id)
                {
                    items.RemoveAt(i);
                    return;
                }
            }
        }

        private List<Topic> GetTopikList()
        {
            List<Topic> topics = new List<Topic>();
            foreach (SubjectItem si in Subjects.Instance.Items)
            {
                if (!Table.Instance.HasSubjectItem(si))
                    continue;
                List<Topic> top = Topiki.Instance.SelectSubject(si.ID);
                foreach (Topic t in top)
                {
                    Topic tp = new Topic();
                    tp.Hours = t.Hours;
                    tp.ID = t.ID;
                    tp.Subject = t.Subject;
                    tp.Theme = t.Theme;
                    topics.Add(tp);
                }
            }
            return topics;
        }

        public List<NagruzkaItem> Generate(DateTime start, DateTime end)
        {

            int totalDipHours = 0;
           
            
            foreach (Topic t in Topiki.Instance.Items)
            {
                if (t.Subject.LessonType == LessonTypes.Дипломное||t.Subject.LessonType == LessonTypes.Курсовое)
                {                   
                    totalDipHours += t.Hours;
                }
                

            }
            TimeSpan span = end.Subtract(start);
            int numNedel = span.Days / 7;
            double averageDipDay = totalDipHours / ((double)numNedel*6);
            
            double summa=0;
            List<Topic> listDipTopic = new List<Topic>();
            
            for (int i = 0; i < Subjects.Instance.Items.Length; i++)
            {
                if (Subjects.Instance.Items[i].LessonType == LessonTypes.Дипломное ||
                    Subjects.Instance.Items[i].LessonType == LessonTypes.Курсовое)
                {
                    List<Topic> top = Topiki.Instance.SelectSubject(Subjects.Instance.Items[i].ID);
                    foreach (Topic t in top)
                    {
                        Topic tp = new Topic();
                        tp.Hours = t.Hours;
                        tp.ID = t.ID;
                        tp.Subject = t.Subject;
                        tp.Theme = t.Theme;
                        listDipTopic.Add(tp);
                    }
                }
                
            }

            Weeks week = Weeks.Red;
            List<Topic> topics = GetTopikList();
            List<Nedela> semestr = new List<Nedela>();
            Nedela etaNedela = new Nedela();
            while ((topics.Count > 0)  &&  (start < end) )           
            {
                for (int i = 0; i < 6; i++)
                {
                    List<TableItem> tbItems = Table.Instance.GetItemsAtDay((Days)i, week);
                    for (int j = 0; j < 8; j++)
                    {
                        TableItem ti = null;
                        foreach (TableItem t in tbItems)
                        {
                            if (t.Pair == j)
                                ti = t;
                        }
                        if (ti == null)
                            continue;
                        Topic tp = null;
                        foreach (Topic topic in topics)
                        {
                            if (topic.Subject == ti.Item)
                            {
                                tp = topic;
                                break;
                            }
                        }
                        if (tp == null)
                            continue;
                        NagruzkaItem ni = new NagruzkaItem();
                        ni.ID = Nagruzki.Instance.FreeID;
                        maxID++;
                        ni.Hour = 2;
                        ni.Chislo = start.ToShortDateString();
                        ni.SubjectItem = ti.Item;
                        ni.Theme = tp.Theme;
                        etaNedela.Dni[i].Add(ni);
                        tp.Hours -= 2;
                        
                        if (tp.Hours < 1)
                            topics.Remove(tp);
                    }

                    if (summa < 2)
                        summa += averageDipDay;
                    else
                    {
                        if (listDipTopic.Count > 0)
                        {
                            NagruzkaItem ni = new NagruzkaItem();
                            ni.ID = Nagruzki.Instance.FreeID;
                            maxID++;
                            ni.Chislo = start.ToShortDateString();
                            ni.Hour = 2;
                            ni.SubjectItem = listDipTopic[0].Subject;
                            ni.Theme = listDipTopic[0].Theme;
                            etaNedela.Dni[i].Add(ni);
                            listDipTopic[0].Hours -= 2;
                            if (listDipTopic[0].Hours < 1)
                                listDipTopic.Remove(listDipTopic[0]);
                            summa = 0;
                        }
                    }

                    start = start.AddDays(1);
                }
                start = start.AddDays(1);
                semestr.Add(etaNedela);
                etaNedela = new Nedela();
                week = (Weeks)(1 - (int)week);
            }    

            

                return AddItems(semestr);
        }

        

        List<NagruzkaItem> AddItems(List<Nedela> semestr)
        {
            List<NagruzkaItem> newItems = new List<NagruzkaItem>();
            foreach (Nedela n in semestr)
            {
                for (int i = 0; i < 6; i++)
                {
                    items.AddRange(n.Dni[i]);
                    newItems.AddRange(n.Dni[i]);
                }
            }
            return newItems;
        }
    }
}
